<?php

namespace app\admin\controller\fastflow\flow;

use app\admin\model\fastflow\flow\EbillCopy;
use app\admin\model\fastflow\flow\Ebill;
use app\common\controller\Backend;
use fastflow\api;
use think\Hook;
use think\Loader;

/**
 * 流程运行
 *
 * @icon fa fa-o
 */
class Run extends Backend
{
    protected $model = null;
    protected $noNeedRight = [
        'start',
        'agree',
        'back',
        'sign',
        'getSelectpageWorkers',
        'getStartStepNeedSelectWorkerSteps',
        'getStartDynamicSteps',
    ];

    public function _initialize()
    {
        Hook::add('fastflow_before_start', 'app\\admin\\behavior\\Fastflow');
        Hook::add('fastflow_after_start', 'app\\admin\\behavior\\Fastflow');
        Hook::add('fastflow_before_agree', 'app\\admin\\behavior\\Fastflow');
        Hook::add('fastflow_after_agree', 'app\\admin\\behavior\\Fastflow');
        Hook::add('fastflow_before_back', 'app\\admin\\behavior\\Fastflow');
        Hook::add('fastflow_after_back', 'app\\admin\\behavior\\Fastflow');
        Hook::add('fastflow_before_sign', 'app\\admin\\behavior\\Fastflow');
        Hook::add('fastflow_after_sign', 'app\\admin\\behavior\\Fastflow');
        Hook::add('fastflow_before_end', 'app\\admin\\behavior\\Fastflow');
        Hook::add('fastflow_after_end', 'app\\admin\\behavior\\Fastflow');
        $this->api = new api(new CustomMessage(), $this);
        $this->view->assign(['carbon_scope' => $this->api->getCarbonScope()]);
        parent::_initialize();
    }


    public function start()
    {
        if ($this->request->isGet()) {
            $bill = input('bill');
            $bill_id = input('bill_id');
            $flows = $this->api->getUseableFlowByBill($bill);
            if (!$flows) {
                $flows = [];
            }
            $this->view->assign(['flows' => $flows, '$bill_id', 'bill' => $bill, 'bill_id' => $bill_id]);
            $scope = $this->api->getDynamicSelectScope();
            $this->assignconfig([
                'scope' => $scope,
                'bill' => $bill,
                'bill_id' => $bill_id,
                'controller_url' => $this->getBillControllerUrl($bill),
                'bill_fields' => $this->getBillFields($bill),
                'can_edit_fields' => $this->getCanEditFields($bill, $bill_id),
            ]);

            return $this->view->fetch();
        }
        if ($this->request->isPost()) {
            $params = input('row/a');
            if (!isset($params['flow_id'])) {
                return ['code' => 0, 'msg' => '未选择流程'];
            }
            $startAuth = (new api())->checkStartAuth($params['flow_id']);
            if (!$startAuth) {
                return ['code' => 0, 'msg' => '您没有权限发起该流程审批'];
            }
            if ($params['ebill_id'] != '') {
                //先清除之前附加的ebill
                $ebill_copy_model = new EbillCopy();
                $ebill_copy_model->where(['bill' => $params['bill'], "bill_id" => $params['bill_id']])->delete();
                $this->appendEbill($params['bill_id'], $params['ebill_id']);
            }
            return $this->api->startFlow($params);
        }
    }

    public function agree()
    {
        if ($this->request->isGet()) {
            $thread_id = input('thread_id');
            $process = $this->api->getProcess($this->api->getThreadById($thread_id)['process_id']);
            $flow_id = $process['flow_id'];
            $have_dynamic = $this->api->getIfHaveDynamicSteps($flow_id, $thread_id);
            if ($have_dynamic) {
                $scope = $this->api->getDynamicSelectScope();
                $dynamic_step_data = $this->api->getCurrentDynamicSteps($flow_id, $thread_id);
                $this->view->assign(['scope' => $scope, 'dynamic_step_data' => $dynamic_step_data]);
                $this->assignconfig(['dynamic_step_data' => $dynamic_step_data]);
            }

            $ebill_copy_id = $this->getEbillCopyId($process['bill'], $process['bill_id']);

            $this->view->assign(['thread_id' => $thread_id, 'flow_id' => $flow_id, 'have_dynamic' => $have_dynamic, 'ebill_id' => $ebill_copy_id]);
            $this->assignconfig([
                'bill' => $process['bill'],
                'bill_id' => $process['bill_id'],
                'thread_id' => $thread_id,
                'controller_url' => $this->getBillControllerUrl($process['bill']),
                'bill_fields' => $this->getBillFields($process['bill']),
                'can_edit_fields' => $this->getCanEditFields($process['bill'], $process['bill_id'], $thread_id),
                'ebill_id' => $ebill_copy_id,
            ]);
            return $this->view->fetch();
        }
        if ($this->request->isPost()) {
            $params = input('row/a');
            return $this->api->agreeFlow($params);
        }
    }


    public function back()
    {
        if ($this->request->isGet()) {
            $thread_id = input('thread_id');
            $thread = $this->api->getThreadById($thread_id);
            $process = $this->api->getProcess($thread['process_id']);
            $flow_id = $process['flow_id'];
            $canback_presteps = $this->api->getCanBackPreStep($flow_id, $process['id'], $thread['step_id']);

            $ebill_copy_id = $this->getEbillCopyId($process['bill'], $process['bill_id']);

            $this->view->assign(['thread_id' => $thread_id, 'flow_id' => $flow_id, 'canback_presteps' => $canback_presteps, 'ebill_id' => $ebill_copy_id]);
            $this->assignconfig([
                'bill' => $process['bill'],
                'bill_id' => $process['bill_id'],
                'thread_id' => $thread_id,
                'controller_url' => $this->getBillControllerUrl($process['bill']),
                'bill_fields' => $this->getBillFields($process['bill']),
                'can_edit_fields' => $this->getCanEditFields($process['bill'], $process['bill_id'], $thread_id),
                'ebill_id' => $ebill_copy_id,
            ]);
            return $this->view->fetch();
        }
        if ($this->request->isPost()) {
            return $this->api->backFlow(input('row/a'));
        }
    }


    public function sign()
    {
        if ($this->request->isGet()) {
            $thread_id = input('thread_id');
            $process = $this->api->getProcess($this->api->getThreadById($thread_id)['process_id']);
            $flow_id = $process['flow_id'];
            $scope = $this->api->getSignScope();

            $ebill_copy_id = $this->getEbillCopyId($process['bill'], $process['bill_id']);

            $this->view->assign(['thread_id' => $thread_id, 'flow_id' => $flow_id, 'scope' => $scope, 'ebill_id' => $ebill_copy_id]);
            $this->assignconfig([
                'bill' => $process['bill'],
                'bill_id' => $process['bill_id'],
                'thread_id' => $thread_id,
                'controller_url' => $this->getBillControllerUrl($process['bill']),
                'bill_fields' => $this->getBillFields($process['bill']),
                'can_edit_fields' => $this->getCanEditFields($process['bill'], $process['bill_id'], $thread_id),
                'ebill_id' => $ebill_copy_id,
            ]);
            return $this->view->fetch();
        }
        if ($this->request->isPost()) {
            return $this->api->signFlow(input('row/a'));
        }
    }

    public function getSelectpageWorkers()
    {
        return (new api())->getSelectpageWorkers();
    }


    public function getStartDynamicSteps()
    {
        return (new api())->getStartDynamicSteps();
    }

    private function getCanEditFields($bill, $bill_id, $thread_id = null)
    {
        return (new api())->getCanEditFields($bill, $bill_id, $thread_id);
    }

    private function getBillFields($bill)
    {
        return (new api())->getBillFields($bill);
    }

    private function getBillControllerUrl($bill)
    {
        $flowBillRow = (new \app\admin\model\fastflow\flow\Bill())->where(['bill_table' => $bill])->find();
        $url = Loader::parseName($flowBillRow['controller'], 0);
        $url = str_replace('/_', '/', $url);
        return $url;
    }

    private function appendEbill($bill_id, $ebill_id)
    {
        $ebill_row = (new Ebill())->find($ebill_id)->toArray();
        $ebill_copy_model = new EbillCopy();
        if ($ebill_row) {
            unset($ebill_row['id']);
            unset($ebill_row['createtime']);
            unset($ebill_row['updatetime']);
            $ebill_row['bill_id'] = $bill_id;
            $ebill_copy_model->insert($ebill_row);
        }
    }

    private function getEbillCopyId($bill, $bill_id)
    {
        $ebill_copy = (new EbillCopy())->where(['bill' => $bill, 'bill_id' => $bill_id])->find();
        if ($ebill_copy) {
            $ebill_copy = $ebill_copy->toArray();
            return $ebill_copy['id'];
        }
        return null;
    }

    //添加签章数据，状态0，待发起
    public function addSignature()
    {
        $params = input('');
        $bill_row = $this->api->getBillRow($params['bill'], $params['bill_id']);
        return ['code' => 1, 'msg' => '操作成功'];
    }

    //发起审批之前回调
    public function beforeStartCallback(&$params)
    {
        Hook::listen('fastflow_before_start', $params);
    }

    //发起审批之后回调
    public function afterStartCallback(&$params)
    {
        Hook::listen('fastflow_after_start', $params);
    }

    //同意之前回调
    public function beforeAgreeCallback(&$params)
    {
        Hook::listen('fastflow_before_agree', $params);
    }

    //同意之后回调
    public function afterAgreeCallback(&$params)
    {
        Hook::listen('fastflow_after_agree', $params);
    }

    //驳回之前回调
    public function beforeBackCallback(&$params)
    {
        Hook::listen('fastflow_before_back', $params);
    }

    //驳回之后回调
    public function afterBackCallback(&$params)
    {
        Hook::listen('fastflow_after_back', $params);
    }

    //会签之前回调
    public function beforeSignCallback(&$params)
    {
        Hook::listen('fastflow_before_sign', $params);
    }

    //会签之后回调
    public function afterSignCallback(&$params)
    {
        Hook::listen('fastflow_after_sign', $params);
    }

    //结束之前回调
    public function beforeEndCallback(&$params)
    {
        Hook::listen('fastflow_before_end', $params);
    }

    //结束之后回调
    public function afterEndCallback(&$params)
    {
        Hook::listen('fastflow_after_end', $params);
    }

}